#!/bin/sh
# inject config data into container
#@author xukaixing@hotmail.com & andy.ten@tom.com
# 执行失败后立即退出（返回值 为 非零），而不继续往下执行
set -e

#init settings
init(){
  echo "AUTHOR: xukaixing@hotmail.com & andy.ten@tom.com"
  uname -a
}

# runJavaProject
runJavaProject(){
  # {var:-default_value}
  # 当var 不存在，或者值为空时，返回default_value
  # {var:=default_value}
  # 当var 不存在，则返回default_value,并且对var赋值default_value
  # {var:+default_value}
  # 当var 不存在，或者值为空时，不返回信息，只有var有值时，default_value
  # default java settings
  # 不使用任何修饰符修饰的都是全局变量 ，局部变量定义用local
  JAVA_RUN_PORT="-Dserver.port=${PORT:-8080}"
  echo "CONTAINER-PORT: ${PORT}"

  DEFAULT_JAVA_OPTS=" -XX:MaxRAMPercentage=50.0 -XX:InitialRAMPercentage=50.0 -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m -Xss512K -XX:MaxDirectMemorySize=128m"
  JAVA_OPTS=${JAVA_OPTS:-${DEFAULT_JAVA_OPTS}}
  JAVA_OPTS="${JAVA_RUN_PORT} ${JAVA_OPTS}"
  # default java tool settings
  DEFAULT_PROFILE=" -Dspring.profiles.active=${PROFILE} "
  JAVA_TOOL_OPTS="${DEFAULT_PROFILE} ${JAVA_TOOL_OPTS} "

  #default gc settings
  DEFAULT_GC_OPTS=" -XX:+UseG1GC -XX:G1ReservePercent=20 "
  GC_OPTS=${GC_OPTS:-${DEFAULT_GC_OPTS}}

  #JDK version diff  default settings.
  set +e
  # jdk8
  if java -version 2>&1|grep 'version'|grep "1.8">>/dev/null 2>&1
  then
    export  JAVA_OPTS=" -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap ${GC_OPTS} -Xloggc:/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=2M  -XX:+PrintGCDateStamps -XX:-PrintTenuringDistribution ${JAVA_OPTS} "
  # jdk11
  elif java -version 2>&1|grep 'version'|grep "11">>/dev/null 2>&1
  then
    export JAVA_OPTS=" ${GC_OPTS} -Xlog:gc:/gc.log -XX:+PrintCommandLineFlags ${JAVA_OPTS}"
  else
    export JAVA_OPTS=" ${GC_OPTS} -Xlog:gc:/gc.log -XX:+PrintCommandLineFlags ${JAVA_OPTS}"
  fi

  # tool options settings.
  export JAVA_TOOL_OPTS="${JAVA_TOOL_OPTS}"
  #echo "JAVA_TOOL_OPTS: ${JAVA_TOOL_OPTS}"

  set -e

  #detect skywalking settings.
  APM_JAR=${APM_JAR:-"/apm-agent/apm-agent.jar"}
  set +e
  mkdir -p /apm-agent
  echo "INFO: if your want to enable apm, please mount your agent into container's path: ${APM_JAR}"
  ls "${APM_JAR}" 2>/dev/null
  # $? 代表上一个命令执行后的退出状态
  rv="${?}"
  set -e
  # -a 逻辑“与” –o 逻辑“或”
  if [ "${SKYWALKING}" = "true" -a ${rv} -eq 0 ];then
      echo "INFO: ${APM_JAR} exist, enable APM."
      export APM_OPTS=" -javaagent:${APM_JAR} \
      -Dskywalking.agent.service_name=${SERVICE_NAME} \
      -Dskywalking.collector.backend_service=${APM_COLLECTOR:-apm-collector:11800} \
      -Dskywalking.logging.max_history_files=1 \
       ${APM_OPTS} "
      # 将执行的每一条命令和结果依次打印出来, 执行过的脚本命令打印到标准输出。
      set +xv
  else
      echo "INFO: ${APM_JAR} not exit in container, ignore."
  fi
  echo "APM_OPTS=${APM_OPTS}"

  #final JAVA_OPTS settings.

  JAVA_OPTS="${APM_OPTS} ${JAVA_OPTS} ${JAVA_TOOL_OPTS}"

  echo "INFO: auto detect find jar on /app and then bootup..."
  #choise biggest jar
  # grep -v NOT 操作，反向匹配
  # grep -e 正则表达式
  # sort 默认的排序方式是升序,-r:改成降序
  # sort -n:以数值来排序（解决10比2小的情况）
  # sort -k 以第几列进行排序
  # awk 文本过滤
  # awk  '{print $NF}' 使用awk截取某个文件夹下面的所有文件名
  # head -n 1 显示文件的第一行（只有一个jar匹配）
  jar=$(find /app/*.jar -ls | grep -v  -e *sources.jar -e  *tests.jar |sort -r -n -k7 |awk  '{print $NF}' |head -n 1)
  echo "JAR=${jar}"

  echo "PROFILE: ${PROFILE}"
  echo "SERVICE_NAME: ${SERVICE_NAME}"
  echo "SKYWALKING: ${SKYWALKING}"

  echo "JAVA_OPTS=${JAVA_OPTS}"
  # -n $string 如果string 非空(非0），返回0(true)
  if [ -n "${jar}" ];then
    echo "run ${jar}"
    eval "exec java ${JAVA_OPTS} -jar ${jar}"
  else
    echo "cant detect jar package in  /app, will exit"
    sleep 20;
    exit 1
  fi
}

runNginxProject(){
  echo " Nginx project run"
}

runNodeProject(){
  echo " Node project run"
}

# checkSourceType and run Project
checkAndRunProject(){
  # 返回值 为 非零 将 会 继续 执行
  set +e
  # 0:表示键盘输入(stdin)
  # 1:表示标准输出(stdout),系统默认是1
  # 2:表示错误输出(stderr)
  # /dev/null 因为这些文件描述符输出的字符串，总是会显示出来的。在shell编程，操作到某一条命令的返回结果，不想要这个时候又不想让这个输出结果打印到屏幕上，就可以重定向到/dev/null这个文件来，由/dev/null这个文件负责处理后事,这个文件接收到的任何数据都会被丢弃
  # >:表示重定向到
  # &:表示等同于
  if which java >/dev/null 2>&1; then
    set -e
    echo "This is a Java Project."
    runJavaProject
  elif which nginx >/dev/null 2>&1; then
    set -e
    echo "This is a Nginx Project."
    runNginxProject
  elif which npm >/dev/null 2>&1;then
    echo "This is a Node Project."
    runNodeProject
  else
    set -e
    echo "This Project Settings not build-in,Set docker-entrypoint.sh Script Manual. "
    sleep 20;
    exit 1;
  fi
}

#main
main(){
  init
  checkAndRunProject
}

#script main entrypoint
#
main
